package com.wk.aidldemo;
import android.app.Service;
import android.content.Intent;
import android.os.Binder;
import android.os.Handler;
import android.os.IBinder;
import android.os.Message;
import android.os.RemoteCallbackList;
import android.os.RemoteException;

import androidx.annotation.NonNull;
import androidx.annotation.Nullable;

import com.wk.aidldemo.tool.WkLogTool;
import com.wk.aidldemo.tool.tasktool.HeartBeatTask;
import com.wk.aidldemo.tool.tasktool.WkHeartBeatTool;
import com.wk.aidldemo.wkAidl.Book;
import com.wk.aidldemo.wkAidl.IBookManager;
import com.wk.aidldemo.wkAidl.IOnNewBookArrivedListener;

import java.lang.ref.WeakReference;
import java.util.List;
import java.util.concurrent.CopyOnWriteArrayList;

/**
 * Service 是运行在主线程中的，所以要用子线程执行耗时操作。。
 */
public class BookManagerService extends Service {
    private CopyOnWriteArrayList<Book> mBookList = new CopyOnWriteArrayList<>();
    private RemoteCallbackList<IOnNewBookArrivedListener> mListenerList = new RemoteCallbackList<>();
    private WkHeartBeatTool wkHeartBeatTool = new WkHeartBeatTool();

    @Override
    public void onCreate() {
        super.onCreate();
        Book book = new Book(  "默认书本"+System.currentTimeMillis()) ;
        book.bookId = mBookList.size()+1;
        mBookList.add(book);
    }

    private Handler mHandler = new MyHandler1(this)  ;
    private static class MyHandler1 extends Handler {
        private final WeakReference<BookManagerService> weakReference;

        MyHandler1(BookManagerService controller) {
            weakReference = new WeakReference<>(controller );
        }

        @Override
        public void handleMessage(@NonNull Message msg) {
            BookManagerService holder = weakReference.get() ;
            if(holder==null){
                return;
            }
            Book book = (Book) msg.obj;
            holder.onBookCreateCallBack(book) ;
        }
    }

    private void onBookCreateCallBack(Book book){
        int num = mListenerList.beginBroadcast();
        for (int i = 0; i < num; ++i) {
            // 给注册这个接口的所有客户端发送回调消息
            IOnNewBookArrivedListener listener = mListenerList.getBroadcastItem(i);
            try {
                listener.onNewBookArrived(book);
            } catch (RemoteException e) {
                e.printStackTrace();
            }
        }
        mListenerList.finishBroadcast();
    }

    private void onNewBookArrived(final Book book)  {
        wkHeartBeatTool.startDelayedAction(new HeartBeatTask() {
            @Override
            public void run() {
                book.bookId = mBookList.size()+1;
                mBookList.add(book);
                Message msg = new Message();
                msg.obj =book ;
                mHandler.sendMessage(msg); // 向Handler发送消息,更新UI
            }
        } ,500); //模拟耗时操作
    }

    @Nullable
    @Override public IBinder onBind(Intent intent) {
        return mBinder;
    }

    private Binder mBinder = new IBookManager.Stub() {
        @Override
        public List<Book> getBookList()   {
            return mBookList;
        }

        @Override
        public void addBook(Book book)  {
            onNewBookArrived(book);
        }

        @Override
        public void registerListener(IOnNewBookArrivedListener listener) throws RemoteException {
            mListenerList.register(listener);
            int num = mListenerList.beginBroadcast(); // 获取元素个数，beginBroadcast 必须与finishBroadcast配对使用
            mListenerList.finishBroadcast(); //
            WkLogTool.showLog("注册接口数量="+num);
            // 注册监听(监听客户端进程是否挂掉)
            listener.asBinder() .linkToDeath(myDeathRecipient ,0);
        }

        @Override
        public void unregisterListener(IOnNewBookArrivedListener listener)   {
            mListenerList.unregister(listener);
            int num = mListenerList.beginBroadcast();
            mListenerList.finishBroadcast();
            WkLogTool.showLog("注册接口数量="+num);
            // 取消监听(监听客户端进程是否挂掉)
            listener.asBinder() .unlinkToDeath(myDeathRecipient ,0);
        }
    };



    private IBinder.DeathRecipient myDeathRecipient = new IBinder.DeathRecipient(){
        @Override
        public void binderDied() {
            WkLogTool.showLog("客户端进程被杀掉了，请server释放掉 这个client对应的资源...");
        }
    };

}
